'use client'; import { useState, useEffect } from 'react'; import { useRouter, useParams } from 'next/navigation'; import Link from 'next/link'; import { fetchApi } from '@/lib/utils/client'; import { useStudioContext } from '@/app/studio/context'; import { useRankConfigContext } from '../../context'; import { Separator } from '@/components/ui/separator'; import RankPreviewPanel from '../../_components/RankPreviewPanel'; import RankFormPanel from '../../_components/RankFormPanel'; import { createEmptyForm, formatInput, parseInput } from '../../types'; import type { FormState } from '../../types'; import type { RankConfigItem } from '@/types/response/donation/rankConfig'; export default function RankEditPage() { const router = useRouter(); const { id } = useParams<{ id: string }>(); const numericId = parseInt(id); const { channelID } = useStudioContext(); const { items, loading, setSaving, fetchList } = useRankConfigContext(); const [editingItem, setEditingItem] = useState(null); const [form, setForm] = useState(createEmptyForm()); const [formInitialized, setFormInitialized] = useState(false); const [localSaving, setLocalSaving] = useState(false); // ── items 로드 후 form 초기화 ──────────────────── useEffect(() => { if (formInitialized || items.length === 0) { return; } const found = items.find(item => item.id === numericId); if (found) { setEditingItem(found); setForm({ title: found.title, theme: found.theme, period: found.period, startAt: found.startAt ? formatInput(new Date(found.startAt)) : null, endAt: found.endAt ? formatInput(new Date(found.endAt)) : null, isShowAmount: found.isShowAmount, maxRankCount: found.maxRankCount, nameMode: found.nameMode, isActive: found.isActive, titleFontFamily: found.titleFontFamily, titleFontSizePx: found.titleFontSizePx, titleFontColor: found.titleFontColor, nameDisplayType: found.nameDisplayType, isShowDonationCount: found.isShowDonationCount, isShowGradeIcon: found.isShowGradeIcon, isShowMemberIcon: found.isShowMemberIcon, rank1FontFamily: found.rank1FontFamily, rank1FontSizePx: found.rank1FontSizePx, rank1FontColor: found.rank1FontColor, rank2FontFamily: found.rank2FontFamily, rank2FontSizePx: found.rank2FontSizePx, rank2FontColor: found.rank2FontColor, rank3FontFamily: found.rank3FontFamily, rank3FontSizePx: found.rank3FontSizePx, rank3FontColor: found.rank3FontColor }); setFormInitialized(true); } else if (!loading) { alert('순위 설정을 찾을 수 없습니다.'); router.push('/studio/donation/rank/list'); } }, [items, loading, numericId, formInitialized, router]); // ── 폼 필드 변경 ──────────────────────────────── const handleFormChange = (field: K, value: FormState[K]) => { setForm(prev => ({ ...prev, [field]: value })); }; // ── 저장 ───────────────────────────────────────── const handleSave = async () => { if (!channelID || !editingItem) { return; } if (!form.title.trim()) { alert('제목을 입력해 주세요.'); return; } setLocalSaving(true); setSaving(true); try { await fetchApi('/api/studio/donation/rank/config', { method: 'POST', body: { channelID, id: editingItem.id, ...form, startAt: form.startAt ? (parseInput(form.startAt) || undefined) : undefined, endAt: form.endAt ? (parseInput(form.endAt) || undefined) : undefined } }); alert('수정되었습니다.'); fetchList(); router.push('/studio/donation/rank/list'); } catch (err) { alert(err instanceof Error ? err.message : '저장에 실패했습니다.'); } finally { setLocalSaving(false); setSaving(false); } }; // ── 취소 ───────────────────────────────────────── const handleCancel = () => { router.push('/studio/donation/rank/list'); }; // ── 로딩 중 ────────────────────────────────────── if (!formInitialized) { return
준비 중...
; } return ( <>

후원 순위 수정

< 목록으로
); }